package edu.northwestern.cbits.purple_robot_manager.activities; import android.annotation.SuppressLint; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import edu.northwestern.cbits.purple_robot_manager.R; import edu.northwestern.cbits.purple_robot_manager.logging.LogManager; public class PermissionsActivity extends AppCompatActivity { private static final int REQUEST_PERMISSION = 1; public enum StatusCode { ALL_GRANTED, OPTIONAL_MISSING, REQUIRED_MISSING } private class Permission { public String name = null; public String label = null; public boolean enabled = false; public boolean required = false; } public static String status(Context context) { List<String> permissions = PermissionsActivity.allPermissions(context); int total = permissions.size(); int granted = 0; int missing = 0; for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) granted += 1; else missing += 1; } return context.getString(R.string.status_permissions, total, granted, missing); } public static StatusCode statusCode(Context context) { List<String> permissions = PermissionsActivity.allPermissions(context); String[] requiredPermissions = context.getResources().getStringArray(R.array.required_permissions); int missing = 0; int required = 0; for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { missing += 1; for (String requiredPermission : requiredPermissions) { if (requiredPermission.equals(permission)) required += 1; } } } if (required > 0) return StatusCode.REQUIRED_MISSING; else if (missing > 0) return StatusCode.OPTIONAL_MISSING; return StatusCode.ALL_GRANTED; } public static List<String> allPermissions(Context context) { ArrayList<String> permissions = new ArrayList<>(); String[] systemOnly = context.getResources().getStringArray(R.array.permissions_system_only); try { PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS); if (info.requestedPermissions != null) { for (String permission : info.requestedPermissions) { boolean include = true; for (String systemPermission : systemOnly) if (systemPermission.equals(permission)) include = false; if (include) permissions.add(permission); } } } catch (PackageManager.NameNotFoundException e) { LogManager.getInstance(context).logException(e); } return permissions; } @Override @SuppressLint("SimpleDateFormat") protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getSupportActionBar().setTitle(R.string.title_permissions); this.setContentView(R.layout.layout_permissions_activity); this.getSupportActionBar().setDisplayHomeAsUpEnabled(true); } public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { this.finish(); return true; } return super.onOptionsItemSelected(item); } protected void onResume() { super.onResume(); this.refreshList(); } private void refreshList() { this.getSupportActionBar().setSubtitle(PermissionsActivity.status(this)); final PermissionsActivity me = this; String[] required = this.getResources().getStringArray(R.array.required_permissions); ListView list = (ListView) this.findViewById(R.id.list_permissions); ArrayList<Permission> permissions = new ArrayList<>(); for (String permission : PermissionsActivity.allPermissions(this)) { Permission p = new Permission(); p.name = permission; p.label = PermissionsActivity.getLabel(this, permission); if (ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) p.enabled = true; else p.enabled = false; for (String requiredPermission : required) { if (requiredPermission.equals(p.name)) p.required = true; } permissions.add(p); } Collections.sort(permissions, new Comparator<Permission>() { @Override public int compare(Permission one, Permission two) { if (one.enabled != two.enabled) { if (one.enabled) return 1; return -1; } if (one.required != two.required) { if (one.required) return -1; return 1; } return one.label.compareToIgnoreCase(two.label); } }); ArrayAdapter<Permission> adapter = new ArrayAdapter<Permission>(this, R.layout.layout_permission_row, permissions) { @SuppressLint("InflateParams") public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) me.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.layout_permission_row, null); } final Permission permission = this.getItem(position); CheckBox nameField = (CheckBox) convertView.findViewById(R.id.text_permission_name); nameField.setText(permission.label); nameField.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // Do nothing... } }); nameField.setChecked(permission.enabled); nameField.setEnabled(permission.enabled != true); nameField.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton arg0, boolean isSelected) { ActivityCompat.requestPermissions(me, new String[]{ permission.name }, PermissionsActivity.REQUEST_PERMISSION); } }); TextView requiredLabel = (TextView) convertView.findViewById(R.id.text_permission_required); if (permission.required) requiredLabel.setVisibility(View.VISIBLE); else requiredLabel.setVisibility(View.GONE); final View view = convertView; convertView.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { CheckBox nameField = (CheckBox) view.findViewById(R.id.text_permission_name); nameField.setChecked(nameField.isChecked() == false); } }); return convertView; } }; list.setAdapter(adapter); } public static String getLabel(Context context, String permission) { String idName = "permission_" + permission.toLowerCase().replace(".", "_"); int id = context.getResources().getIdentifier(idName, "string", context.getPackageName()); if (id != 0) return context.getString(id); return permission; } public static String getTitle(Context context, String permission) { String idName = "permission_title_" + permission.toLowerCase().replace(".", "_"); int id = context.getResources().getIdentifier(idName, "string", context.getPackageName()); if (id != 0) return context.getString(id); return permission; } public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == PermissionsActivity.REQUEST_PERMISSION) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, R.string.toast_permission_granted, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, R.string.toast_permission_denied, Toast.LENGTH_SHORT).show(); } } this.refreshList(); } }